<?php

declare(strict_types=1);
/**
 * This file is part of MoChat.
 * @link     https://mo.chat
 * @document https://mochat.wiki
 * @contact  group@mo.chat
 * @license  https://github.com/mochat-cloud/mochat/blob/master/LICENSE
 */
namespace MoChat\Plugin\ContactTodo\Queue;

use Hyperf\AsyncQueue\Annotation\AsyncQueueMessage;
use Hyperf\Contract\StdoutLoggerInterface;
use Hyperf\Di\Annotation\Inject;
use Hyperf\Utils\Codec\Json;
use MoChat\App\Corp\Contract\CorpContract;
use MoChat\App\Corp\Logic\AppTrait;
use MoChat\App\Utils\Url;
use MoChat\App\WorkAgent\QueueService\MessageRemind;
use MoChat\App\WorkContact\Contract\WorkContactContract;
use MoChat\Plugin\ContactTodo\Contract\ContactTodoContract;

/**
 * 企业微信 待办提醒.
 */
class TodoRemindQueue
{
    use AppTrait;

    /**
     * @Inject
     * @var ContactTodoContract
     */
    protected $contactEmployeeTodo;

    /**
     * @Inject
     * @var WorkContactContract
     */
    protected $workContact;

    /**
     * @Inject
     * @var CorpContract
     */
    protected $corpContract;

    /**
     * @Inject
     * @var StdoutLoggerInterface
     */
    private $logger;

    /**
     * @AsyncQueueMessage(pool="remind")
     * @param $corpId
     */
    public function handle($corpId): void
    {
        // 定时提醒
        $this->timingRemind($corpId);
        // 周期提醒
        $this->cycleRemind($corpId);
    }

    /**
     * 定时提醒.
     * @param $corpId
     */
    protected function timingRemind($corpId)
    {
        $todo = $this->contactEmployeeTodo->getContactTodoByCorpIdType($corpId, 1, ['id', 'employee_id', 'contact_id', 'content', 'day', 'time', 'wx_user_id', 'wx_external_userid']);
        foreach ($todo as $item) {
            if (date('Y-m-d') !== $item['day'] || date('H:i') !== $item['time']) {
                continue;
            }
            $contact = $this->workContact->getWorkContactById($item['contactId'], ['name']);
            $this->sendRemind($corpId, $item['employeeId'], $item['contactId'], $contact['name'], $item['wxUserId'], $item['content']);
            $this->contactEmployeeTodo->updateContactTodoById($item['id'], ['status' => 1]);
        }
    }

    protected function cycleRemind($corpId)
    {
        $todo = $this->contactEmployeeTodo->getContactTodoByCorpIdType($corpId, 2, ['id', 'employee_id', 'contact_id', 'content', 'day', 'time', 'wx_user_id', 'wx_external_userid', 'repeat', 'end_repeat', 'send_time', 'send_num']);
        foreach ($todo as $item) {
            // 今天发送过了
            if (! empty($repeat['sendTime']) && date('Y-m-d') === date('Y-m-d', strtotime($repeat['sendTime']))) {
                continue;
            }
            // 1、提醒时间判断
            if (date('H:i') !== $item['time']) {
                continue;
            }
            // 2、重复规则判断
            $repeat = Json::decode($item['repeat']);
            // 每周重复
            if ((int) $repeat['repeatType'] === 2 && date('w') !== date('w', strtotime($item['day']))) {
                continue;
            }
            // 每月重复
            if ((int) $repeat['repeatType'] === 3 && date('d') !== date('d', strtotime($item['day']))) {
                continue;
            }
            // 自定义重复
            if ((int) $repeat['repeatType'] === 4) {
                $diff = 0;
                if (! empty($repeat['sendTime'])) {
                    $diff = date_diff(date_create(date('Y-m-d', strtotime('2021-08-01 14:45:19'))), date_create(date('Y-m-d')));
                    $diff = $diff->format('%R%a');
                }
                // 自定义重复-频率（日）
                if ((int) $repeat['rateType'] === 1 && $diff > 0 && $diff % (int) $repeat['rateNum'] !== 0) {
                    continue;
                }
                // 自定义重复-频率（周）
                if ((int) $repeat['rateType'] === 2 && ! in_array(date('w'), $repeat['dayNum'], true)) {
                    continue;
                }
                // 自定义重复-频率（月）
                if ((int) $repeat['rateType'] === 3 && ! in_array(date('d'), $repeat['dayNum'], true)) {
                    continue;
                }
            }
            // 3、结束重复规则判断
            $status = 2;
            $endRepeat = Json::decode($item['endRepeat']);
            // 重复次数
            if ((int) $endRepeat['endRepeatType'] === 2) {
                if ((int) $endRepeat['repeatNum'] === $item['sendNum'] + 1) {
                    $status = 1;
                }
                if ($item['sendNum'] >= (int) $endRepeat['repeatNum']) {
                    continue;
                }
            }
            // 结束重复时间
            if ((int) $endRepeat['endRepeatType'] === 3) {
                if (date('Y-m-d') === $endRepeat['endDay']) {
                    $status = 1;
                }
                if (date('Y-m-d') >= $endRepeat['endDay'] && date('H:i') >= $endRepeat['endTime']) {
                    continue;
                }
            }
            $contact = $this->workContact->getWorkContactById($item['contactId'], ['name']);
            $this->sendRemind($corpId, $item['employeeId'], $item['contactId'], $contact['name'], $item['wxUserId'], $item['content']);
            $this->contactEmployeeTodo->updateContactTodoById($item['id'], ['send_time' => date('Y-m-d H:i:s'), 'send_num' => $item['sendNum'] + 1, 'status' => $status]);
        }
    }

    /**
     * 发送提醒.
     * @param $corpId
     * @param $employeeId
     * @param $contactId
     * @param $contactName
     * @param $wxUserId
     * @param $content
     */
    protected function sendRemind($corpId, $employeeId, $contactId, $contactName, $wxUserId, $content)
    {
        $url = Url::getSidebarBaseUrl() . '/contact?agentId={{agentId}}&contactId=' . $contactId;
        $time = date('Y-m-d H:i');
        $text = "【待办提醒】您有新的待办事项哦！\n" .
            "客户昵称：{$contactName}\n" .
            "待办事项：{$content}\n" .
            "提醒时间：{$time}\n" .
            "<a href='{$url}'>点击查看客户详情</a>";
        $messageRemind = make(MessageRemind::class);
        $messageRemind->sendToEmployee(
            $corpId,
            $wxUserId,
            'text',
            $text
        );
    }
}
